﻿using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.ComponentModel;
namespace MyWebCtrls
{
    /// <summary>
    /// 用于实现可下拉选择，也可编辑的文本框
    /// </summary>
    [ToolboxData("<{0}:ComboxTextBox JQueryPath=\"\" ComboxPluginPath=\"\" SelectDatas=\"\" runat=\"server\"></{0}:ComboxTextBox>")]
    [PersistChildren(false)]
    public class ComboxTextBox : WebControl, IPostBackDataHandler
    {
        /// <summary>
        /// 所引用的 JQuery文件路径
        /// </summary>
        [Category("相关引用文件")]
        [PersistenceMode(PersistenceMode.Attribute)]
        [DefaultValue("")]
        [Browsable(true)]
        [Description("所引用的 JQuery文件路径(可为空，为空时，必须要在页面中放置jquery文件的引用)")]
        public string JQueryPath
        {
            get;
            set;
        }
        /// <summary>
        /// 所引用的 JQuery combox插件文件路径
        /// </summary>
        [Category("相关引用文件")]
        [PersistenceMode(PersistenceMode.Attribute)]
        [DefaultValue("")]
        [Browsable(true)]
        [Description("所引用的 JQuery combox插件文件路径(可为空，为空时，必须要在页面中放置 JQuery combox文件的引用)")]
        public string ComboxPluginPath
        {
            get;
            set;
        }
        /// <summary>
        /// 可供下拉选择的值,多值之间用\"|\"号分隔，如 china|japan|usa|russia
        /// </summary>
        [Category("相关初始值设定")]
        [PersistenceMode(PersistenceMode.Attribute)]
        [DefaultValue("")]
        [Browsable(true)]
        [Description("可供下拉选择的值，多值之间用\"|\"号分隔，如 china|japan|usa|russia ")]
        public string SelectDatas
        {
            get;
            set;
        }      
        /// <summary>
        /// 经格式化，且符合jquery.combobox.js要求的下拉数据
        /// </summary>
        public string FormatedDatas
        {
            get
            {
                return GetDropData();
            }
        }
        /// <summary>
        /// 控件使用的样式文件路径,为了统一，控件的样式名固定为ComboxTextBoxClass,编写样式文件时需要注意，控件使用input type=\"text\"呈现
        /// </summary>
        [Category("相关初始值设定")]
        [PersistenceMode(PersistenceMode.Attribute)]
        [DefaultValue("jquery.combobox.css")]
        [Browsable(true)]
        [Description("控件使用的样式文件路径,为了统一，控件的样式名固定为ComboxTextBoxClass,编写样式文件时需要注意，控件使用input type=\"text\"呈现)")]
        public string CssPath
        {
            get;
            set;
        }  
        /// <summary>
        /// 是否显示图标按钮
        /// </summary>
        [Category("相关初始值设定")]
        [PersistenceMode(PersistenceMode.Attribute)]
        [DefaultValue("")]
        [Browsable(true)]
        [Description("是否显示图标按钮")]
        public bool ShowImage
        {
            get;
            set;
        }
        /// <summary>
        /// 标识下拉按钮的图片路径
        /// </summary>
        [Category("相关初始值设定")]
        [PersistenceMode(PersistenceMode.Attribute)]
        [DefaultValue("dropdown.gif")]
        [Browsable(true)]
        [Description("标识下拉按钮的图片路径，默认为（dropdown.gif)")]
        public string DropdownImage
        {
            get;
            set;
        }    
        /// <summary>
        /// 获取生成的客户端Name
        /// </summary>
        public override string UniqueID
        {
            get
            {
                return this.ID;
            }
        }
        /// <summary>
        /// 获取生成的客户端ID
        /// </summary>
        public override string ClientID
        {
            get
            {
                return this.ID;
            }
        }
        /// <summary>
        /// 获取生成的html tag，默认指定为input
        /// </summary>
        protected override HtmlTextWriterTag TagKey
        {
            get
            {
                return HtmlTextWriterTag.Input;
            }
        }
        /// <summary>
        /// 获取或设置控件的值
        /// </summary>
        public string Text
        {
            get
            {
                object text = ViewState["Text"];
                if (text == null)
                    return string.Empty;
                else
                    return (string)text;
            }
            set
            {
                ViewState["Text"] = value;
            }
        }

        /// <summary>
        /// 添加JS到html header
        /// </summary>
        /// <param name="jsID">JS的ID，防止重复加载</param>
        /// <param name="jsPath">要加载的JS路径</param>
        private void AppendJS(string jsID, string jsPath)
        {
            bool hasJS = false;
            if (!string.IsNullOrEmpty(jsPath))
            {
                foreach (Control ctl in this.Page.Header.Controls)
                {
                    if (string.Compare(ctl.ID, jsID) == 0)
                    {
                        hasJS = true;
                        break;
                    }
                }
            }
            else
            {
                hasJS = true; //jquery路径为空的情况下，默认表示已经有jquery引用了。
            }
            if (!hasJS)
            {
                System.Web.UI.HtmlControls.HtmlGenericControl jsCtl = new System.Web.UI.HtmlControls.HtmlGenericControl();
                jsCtl.ID = jsID;
                jsCtl.TagName = "script";
                jsCtl.Attributes.Add("type", "text/javascript");
                jsCtl.Attributes.Add("language", "javascript");
                jsCtl.Attributes.Add("src", jsPath);
                this.Page.Header.Controls.Add(jsCtl);
            }
        }
        /// <summary>
        /// 添加CSS到html header
        /// </summary>
        /// <param name="cssID">CSS的ID，防止重复加载</param>
        /// <param name="cssPath">要加载的CSS路径</param>
        private void AppendCss(string cssID, string cssPath)
        {
            bool hasCSS = false;
            if (!string.IsNullOrEmpty(cssPath))
            {
                foreach (Control ctl in this.Page.Header.Controls)
                {
                    if (string.Compare(ctl.ID, cssID) == 0)
                    {
                        hasCSS = true;
                        break;
                    }
                }
            }
            else
            {
                hasCSS = true;
            }
            if (!hasCSS)
            {
                System.Web.UI.HtmlControls.HtmlLink link = new System.Web.UI.HtmlControls.HtmlLink();
                link.ID = cssID;
                link.Attributes.Add("type", "text/css");
                link.Attributes.Add("rel", "stylesheet");
                link.Attributes.Add("href", cssPath);
                this.Page.Header.Controls.Add(link);
            }
        }
        /// <summary>
        /// 获取下拉数据值
        /// </summary>
        /// <returns></returns>
        private string GetDropData()
        {
            if (string.IsNullOrEmpty(this.SelectDatas))
                return string.Empty;
            string[] datas = this.SelectDatas.Split('|');
            List<string> Outdatas = new List<string>(datas);
            List<string> convertedData = Outdatas.ConvertAll<string>(str => "'" + str + "'");
            return string.Join(",", convertedData.ToArray());
        }
        /// <summary>
        /// 输出初始化控件的JS
        /// </summary>
        /// <returns>初始化控件的JS</returns>
        private string OutputInitJS()
        {
            StringBuilder sb = new StringBuilder();
            sb.Append("\r\n <script type=\"text/javascript\" language=\"javascript\">");
            sb.Append("\r\n $(function(){");
            sb.Append("\r\n  $('#" + this.ClientID + "').combobox([" + GetDropData() + "],{showImage:"+this.ShowImage.ToString().ToLower()+",imageUrl : '" + this.DropdownImage + "'});");
            sb.Append("\r\n });");
            sb.Append("\r\n </script> \r\n");
            return sb.ToString();
        }
        /// <summary>
        /// OnPreRender
        /// </summary>
        /// <param name="e"></param>
        protected override void OnPreRender(EventArgs e)
        {
            AppendJS("ComboxTextBoxJQuery", this.JQueryPath);
            AppendJS("ComboxTextBoxJPlugin", this.ComboxPluginPath);
            AppendCss("ComboxTextBoxCSS", this.CssPath);
            this.Page.ClientScript.RegisterStartupScript(this.GetType(), this.ID + "ComboxTxtInitJS", OutputInitJS());
            base.OnPreRender(e);
        }
        /// <summary>
        /// AddAttributesToRender
        /// </summary>
        /// <param name="writer"></param>
        protected override void AddAttributesToRender(HtmlTextWriter writer)
        {         
            base.AddAttributesToRender(writer);
            writer.AddAttribute(HtmlTextWriterAttribute.Class, "ComboxTextBoxClass");
            writer.AddAttribute(HtmlTextWriterAttribute.Name, this.UniqueID);
            writer.AddAttribute(HtmlTextWriterAttribute.Type, "text");
            writer.AddAttribute(HtmlTextWriterAttribute.Value, this.Text); //添加这行以显示默认值
        }
        /// <summary>
        /// 控件内容发生改变后引发的事件
        /// </summary>
        public event EventHandler TextChanged;
        /// <summary>
        /// TextChanged事件处理函数
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void OnTextChanged(object sender, EventArgs e)
        {
            if (null != TextChanged)
            {
                TextChanged(sender, e);
            }
        }
        /// <summary>
        /// 返回true引发数据(Text)修改事件
        /// </summary>
        /// <param name="postDataKey"></param>
        /// <param name="postCollection"></param>
        /// <returns></returns>
        public bool LoadPostData(string postDataKey, NameValueCollection postCollection)
        {
            string postedValue = postCollection[postDataKey];
            if (!Text.Equals(postedValue))
            {
                Text = postedValue;
                return true;
            }
            return false;
        }
        /// <summary>
        /// 数据修改事件
        /// </summary>
        public void RaisePostDataChangedEvent()
        {
            OnTextChanged(this, EventArgs.Empty);
        }
    }
}
